package com.pay.paytoken.activity.lock;

import android.content.Context;
import android.content.Intent;
import android.os.Build;

import com.pay.paytoken.R;

import java.util.ArrayList;
import java.util.List;

import appUtils.AppUtil;
import appUtils.FingerprintUtil;
import appUtils.SharedPreferencesManager;
import appUtils.ToastUtil;

import static appUtils.SharedPreferencesManager.LOCK_FINGERPRINT;
import static appUtils.SharedPreferencesManager.LOCK_GESTURE;
import static appUtils.SharedPreferencesManager.LOCK_GESTURE_PASS;

public class LockManager {
    public static final int DIGITAL = 0x1;
    public static final int FINGERPRINT = 0x1 << 1;
    public static final int GESTURE = 0x1 << 2;
    public static final String CANBACK = "canBack";
    public static final String TYPE = "type";
    private final List<LockObserver> mObservers = new ArrayList<>();
    private boolean mHasFingerprint;
    private SharedPreferencesManager mSharedManager;

    private LockManager() {

    }

    private static final class Holder {
        private static final LockManager MANAGER = new LockManager();
    }

    public static LockManager getInstance() {
        return Holder.MANAGER;
    }

    /**
     * 初始化LockManager，判断手机是否存在指纹解锁功能，初始化首选项
     *
     * @param context
     */
    public void init(Context context) {
        mHasFingerprint = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && FingerprintUtil.hasFingerprint();
        mSharedManager = SharedPreferencesManager.getInstance(context);
    }

    /**
     * 获取手机是否存在指纹解锁功能
     *
     * @return
     */
    public boolean getHasFingerprintAU() {
        return mHasFingerprint;
    }

    /**
     * 开启密码解锁界面，有手势密码或指纹密码先启动手势密码或指纹密码解锁界面，如果都没有的话跳入数字解锁密码界面
     *
     * @param context
     */
    public void startLockActivity(Context context) {
        if (lockActivitiesIsTop() || !getLockAble()) {
            return;
        }
        if (mHasFingerprint && getFingerprintAble()) {
            startFingerprintLockActivityIN(context, false);
        } else if (!mHasFingerprint && getGestureAble()) {
            startGestureLockActivityIN(context, false);
        } else {
            startDigitalLockActivityIN(context, false);
        }
    }

    /**
     * 开启数字解锁界面，先判断当前界面是否为密码模块相关界面和是否开启密码模块
     *
     * @param context
     * @param canBack
     */
    public void startDigitalActivity(Context context, boolean canBack) {
        startDigitalLockActivityIN(context, canBack);
    }

    /**
     * 判断当前界面是否为解锁模块相关界面
     *
     * @return
     */
    public boolean lockActivitiesIsTop() {
        Class topAC = AppUtil.getInstance().getTopAC();
        return topAC != null && (topAC.equals(GestureLockActivity.class)
                || topAC.equals(DigitalLockActivity.class) || topAC.equals(GestureSetLockActivity.class)
                || topAC.equals(DigitalSetLockActivity.class) || topAC.equals(DigitalConfirmLockActivity.class));
    }

    /**
     * 设置数字密码
     *
     * @param context
     */
    public void setDigitalLock(Context context) {
        setDigitalLockIN(context, true);
    }

    /**
     * 设置手势密码，先判断密码模块是否开启
     *
     * @param context
     */
    private void setGestureLockIN(Context context) {
        if (getLockAble()) {
            setGestureLockIN(context, true);
        } else {
            setGestureLockAbleIN(false);
            notifyObserversIN(FINGERPRINT, false);
            ToastUtil.showLong(R.string.please_first_set_digital_lock);
        }
    }

    /**
     * 设置手势密码开关，先判断密码模块是否开启，当为关闭手势密码时，清空手势密码数据
     *
     * @param able
     */
    public void setGestureAble(boolean able) {
        if (getLockAble()) {
            setGestureLockAbleIN(able);
            if (!able) {
                clearGestureDigitalIN();
            }
            notifyObserversIN(GESTURE, able);
        } else {
            setGestureLockAbleIN(false);
            clearGestureDigitalIN();
            notifyObserversIN(GESTURE, false);
            ToastUtil.showLong(R.string.please_first_set_digital_lock);
        }
    }

    /**
     * 修改手势密码，先判断密码是否开启，再判断手势密码是否开启器，未开启则执行设置手势密码
     * .开启则执行手势面膜修改界面
     *
     * @param context
     * @param type
     */
    public void updateGesture(Context context, int type) {
        if (!getLockAble()) {
            ToastUtil.showLong(R.string.please_first_set_digital_lock);
            return;
        }
        if (!getGestureAble()) {
            setGestureLockIN(context);
            return;
        }
        Intent intent = new Intent(context, GestureLockActivity.class);
        intent.putExtra(CANBACK, true);
        intent.putExtra(TYPE, type);
        context.startActivity(intent);
    }

    /**
     * 修改数字密码，数字密码是为开启状态则跳入数字确认界面，数字密码是关闭状态则跳入数字密码设置界面
     *
     * @param context
     */
    public void updateDigitalLock(Context context) {
        if (getLockAble()) {
            context.startActivity(new Intent(context, DigitalConfirmLockActivity.class));
        } else {
            setDigitalLock(context);
        }
    }

    /**
     * 设置指纹开关，先检验密码模块是否开启，在检验是否支持指纹解锁
     *
     * @param context
     * @param able
     */
    public void setFingerprintAble(Context context, boolean able) {
        if (getLockAble()) {
            if (mHasFingerprint) {
                if (!getFingerprintAble() && !FingerprintUtil.getFingerprintEnAble(context)) {
                    ToastUtil.showLong(R.string.please_open_the_phone_unlock_fingerprint);
                    return;
                }
                setFingerprintLockAbleIN(able);
                notifyObserversIN(FINGERPRINT, able);
            }
        } else {
            setFingerprintLockAbleIN(false);
            notifyObserversIN(FINGERPRINT, false);
            ToastUtil.showLong(R.string.please_first_set_digital_lock);
        }
    }

    /**
     * 开启数字解锁界面
     *
     * @param context
     * @param canBack
     */
    private void startDigitalLockActivityIN(Context context, boolean canBack) {
        Intent intent = new Intent();
        intent.setClass(context, DigitalLockActivity.class);
        intent.putExtra(CANBACK, canBack);
        intent.putExtra(TYPE, 0);
        context.startActivity(intent);
    }

    /**
     * 开启数字密码设置界面
     *
     * @param context
     * @param canBack
     */
    private void setDigitalLockIN(Context context, boolean canBack) {
        Intent intent = new Intent(context, DigitalSetLockActivity.class);
        intent.putExtra(CANBACK, canBack);
        context.startActivity(intent);
    }

    /**
     * 开启指纹解锁界面
     *
     * @param context
     * @param canBack 是否可以返回
     */
    private void startFingerprintLockActivityIN(Context context, boolean canBack) {
        Intent intent = new Intent();
        intent.setClass(context, DigitalLockActivity.class);
        intent.putExtra(CANBACK, canBack);
        intent.putExtra(TYPE, 1);
        context.startActivity(intent);
    }

    /**
     * 开启手势解锁界面
     *
     * @param context
     * @param canBack
     */
    private void startGestureLockActivityIN(Context context, boolean canBack) {
        Intent intent = new Intent();
        intent.setClass(context, GestureLockActivity.class);
        intent.putExtra(CANBACK, canBack);
        intent.putExtra(TYPE, 0);
        context.startActivity(intent);
    }

    /**
     * 开启手势设置界面
     *
     * @param context
     * @param canBack
     */
    private void setGestureLockIN(Context context, boolean canBack) {
        Intent intent = new Intent(context, GestureSetLockActivity.class);
        intent.putExtra(TYPE, 0);
        intent.putExtra(CANBACK, canBack);
        context.startActivity(intent);
    }

    /**
     * 重置密码模块（清空所有已保存数据，并开启密码设置界面）
     *
     * @param context
     */
    public void resetLock(Context context) {
        setDigitalLockAbleIN(false);
        setGestureLockAbleIN(false);
        setFingerprintLockAbleIN(false);
        clearDigitalPassIN();
        clearGestureDigitalIN();
        setDigitalLock(context);
    }

    /**
     * 清空所有首选项数据
     */
    public void resetAllPwds() {
        mSharedManager.clean();
    }

    //--------------------密码状态（是否开启密码，是否存在密码）-----------------------//

    /**
     * 查看密码模块是否开启（暂时相当于获取数字密码开启状态）
     *
     * @return
     */
    public boolean getLockAble() {
        return mSharedManager.readBoolean(SharedPreferencesManager.LOCK_DIGITAL, false);
    }

    /**
     * 设置数字密码开关
     *
     * @param able
     */
    private void setDigitalLockAbleIN(boolean able) {
        mSharedManager.saveBoolean(SharedPreferencesManager.LOCK_DIGITAL, able);
    }

    /**
     * 保存数字密码，并开启数字密码开关
     *
     * @param pass
     */
    public void saveDigitalPass(String pass) {
        setDigitalLockAbleIN(true);
        mSharedManager.saveString(SharedPreferencesManager.LOCK_DIGITAL_PASS, pass);
    }

    /**
     * 获取数字密码数据
     *
     * @return
     */
    public String getDigitalPass() {
        return mSharedManager.readString(SharedPreferencesManager.LOCK_DIGITAL_PASS, "");
    }

    /**
     * 清空数字密码数据
     */
    private void clearDigitalPassIN() {
        mSharedManager.saveString(SharedPreferencesManager.LOCK_DIGITAL_PASS, "");
    }

    /**
     * 设置指纹密码开关
     *
     * @param able
     */
    private void setFingerprintLockAbleIN(boolean able) {
        mSharedManager.saveBoolean(SharedPreferencesManager.LOCK_FINGERPRINT, able);
    }

    /**
     * 获取指纹密码开启状态
     *
     * @return
     */
    public boolean getFingerprintAble() {
        return mSharedManager.readBoolean(LOCK_FINGERPRINT, false);
    }

    /**
     * 设置手势密码开关
     *
     * @param able
     */
    private void setGestureLockAbleIN(boolean able) {
        mSharedManager.saveBoolean(SharedPreferencesManager.LOCK_GESTURE, able);
    }

    /**
     * 获取手势密码开启状态
     *
     * @return
     */
    public boolean getGestureAble() {
        return mSharedManager.readBoolean(LOCK_GESTURE, false);
    }

    /**
     * 保存手势密码数据
     *
     * @param pass
     */
    public void saveGesturePass(String pass) {
        setGestureAble(true);
        mSharedManager.saveString(SharedPreferencesManager.LOCK_GESTURE_PASS, pass);
    }

    /**
     * 清空手势密码数据
     */
    private void clearGestureDigitalIN() {
        mSharedManager.saveString(LOCK_GESTURE_PASS, "");
    }

    /**
     * 添加观察者
     *
     * @param observer
     * @return
     */
    public boolean attachObserver(LockObserver observer) {
        return !mObservers.contains(observer) && mObservers.add(observer);
    }

    /**
     * 删除观察者
     *
     * @param observer
     * @return
     */
    public boolean detachObserver(LockObserver observer) {
        return mObservers.contains(observer) && mObservers.remove(observer);
    }

    /**
     * 通知观察者
     *
     * @param index
     * @param able
     */
    private void notifyObserversIN(int index, boolean able) {
        for (LockObserver observer : mObservers) {
            observer.onLockChangeCallBack(index, able);
        }
    }

    public interface LockObserver {
        void onLockChangeCallBack(int index, boolean able);
    }
}